package com.clsz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.clsz.annotation.RedisCache;
import com.clsz.bean.po.CinemaFilmRel;
import com.clsz.bean.po.CinemaInfo;
import com.clsz.bean.po.FilmInfo;
import com.clsz.bean.po.WatchTimes;
import com.clsz.bean.vo.FilmVo;
import com.clsz.bean.vo.WatchDateVo;
import com.clsz.mapper.CinemaFilmRelMapper;
import com.clsz.service.CinemaDetailService;
import com.clsz.utils.ESResponse;
import com.clsz.utils.ESUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class CinemaDetailServiceImpl implements CinemaDetailService {
    @Resource
    private ESUtils esUtils;
    @Resource
    private CinemaFilmRelMapper cinemaFilmRelMapper;
    @Override
    public CinemaInfo getCinema(Integer cinemaId) {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.termQuery("cma_id", cinemaId));
        searchSourceBuilder.query(boolQueryBuilder);
        ESResponse<CinemaInfo> cinema = esUtils.search("cinema", searchSourceBuilder, CinemaInfo.class);
        return cinema.getResCount()==0?null:cinema.getData().get(0);
    }

    @Override
    @RedisCache(duration = 60 * 60)
    public List<FilmVo> getFilmVo(Integer cinemaId) {
        SearchSourceBuilder searchSourceBuilder = null;
        BoolQueryBuilder boolQueryBuilder = null;
        List<FilmVo> filmVoList = new ArrayList<>();

        LambdaQueryWrapper<CinemaFilmRel> cinemaQueryWrapper = Wrappers.lambdaQuery();
        cinemaQueryWrapper.eq(CinemaFilmRel::getCmaId, cinemaId);
        List<CinemaFilmRel> cinemaFilmRelList = cinemaFilmRelMapper.selectList(cinemaQueryWrapper);

        for (CinemaFilmRel cinemaFilmRel : cinemaFilmRelList) {
            FilmVo filmVo = new FilmVo();

            searchSourceBuilder = new SearchSourceBuilder();
            boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.termQuery("film_id", cinemaFilmRel.getFilmId()));
            searchSourceBuilder.query(boolQueryBuilder);
            ESResponse<FilmInfo> filmList = esUtils.search("film", searchSourceBuilder, FilmInfo.class);

            FilmInfo filmInfo = filmList.getData().get(0);
            filmVo.setFilm(filmInfo);
            //获取场次信息
            searchSourceBuilder = new SearchSourceBuilder();
            boolQueryBuilder = new BoolQueryBuilder();
            boolQueryBuilder.must(QueryBuilders.termQuery("cma_id", cinemaId));
            boolQueryBuilder.must(QueryBuilders.termQuery("film_id", cinemaFilmRel.getFilmId()));
            searchSourceBuilder.query(boolQueryBuilder);
            searchSourceBuilder.sort("wt_begintime", SortOrder.ASC);
            ESResponse<WatchTimes> watchTimes = esUtils.search("watch_times", searchSourceBuilder, WatchTimes.class);
            List<WatchTimes> watchTimesList = watchTimes.getData();
            //按日期进行分组
            Set<String> dateSet = new HashSet<>();
            for (WatchTimes watchTimesData : watchTimesList) {
                dateSet.add(watchTimesData.getWdDate());
            }
            //遍历观影日期
            for (String date : dateSet) {
                WatchDateVo watchDateVo = new WatchDateVo();
                watchDateVo.setDate(date);
                //添加场次信息
                for (WatchTimes times : watchTimesList) {
                    //判断是否属于当前日期
                    if (times.getWdDate().equals(date)) {
                        watchDateVo.getWatchTimesList().add(times);
                    }
                }
                filmVo.getWatchDateVoList().add(watchDateVo);
            }
            filmVoList.add(filmVo);
        }
        return filmVoList;
    }
}
